package nimble.dynamic.proxy;

import net.sf.cglib.proxy.Enhancer;
import nimble.dynamic.proxy.action.*;
import nimble.dynamic.proxy.operation.*;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Set;

public class DynamicProxy {

    private static final Logger logger= LoggerFactory.getLogger(DynamicProxy.class);
    
    public static void main(String[] args) throws Exception
    {
        // java 动态代理
        SubOperation subOperation=new SubOperation();
        InvocationHandler handler = new MyOperationProxy(subOperation);
        MyOperation myOperation=(MyOperation) Proxy.newProxyInstance(handler.getClass().getClassLoader(),subOperation.getClass().getInterfaces(),handler);
        myOperation.oper(1,2);
        // CGLIB代理，自己创建
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(AddOperation.class);
        enhancer.setCallback(new MyMethodInterceptor());
        myOperation=(MyOperation)enhancer.create();
        myOperation.oper(1,2);
        // CGLIB代理，使用Enhancer创建
        MyOperation a=(MyOperation) Enhancer.create(SubOperation.class,new MyMethodInterceptor());
        a.oper(2,4);
        //
        Action action;
        action=(Action) Enhancer.create(RunAction.class,new MyMethodInterceptor());
        action.execute("Max Woods");
        //java代理
        RunAction runAction=new RunAction();
        ActionProxy actionProxy=new ActionProxy();
        actionProxy.bind(runAction);
        action=(Action) Proxy.newProxyInstance(actionProxy.getClass().getClassLoader(),runAction.getClass().getInterfaces(),actionProxy);
        action.execute("Max Woods");
        //CGLIB代理
        action=(Action)Enhancer.create(WalkAction.class,new ActionInterceptor());
        action.execute("Max Woods");
        //
        Reflections reflections = new Reflections("nimble.dynamic.proxy.action");
        Set<Class<? extends Action>> interfaces=reflections.getSubTypesOf(Action.class);
        for(Class<? extends Action> b:interfaces)
        {
            if(!Modifier.isAbstract(b.getModifiers()))
            {
                Action action1=b.newInstance();
                actionProxy=new ActionProxy();
                actionProxy.bind(action1);
                action=(Action)Proxy.newProxyInstance(actionProxy.getClass().getClassLoader(),runAction.getClass().getInterfaces(),actionProxy);
                System.out.println("========================");
                action.execute("Max Woods");
            }
//            System.out.println(Modifier.isAbstract(b.getModifiers()));
//            System.out.println("============="+b.getName());
//            if(b.getName().equals(Action.class.getName())) {
//                System.out.println(b.getName());
//            }
        }
    }
}
